package com.wolfking.converter.config;

import com.google.common.collect.Sets;
import com.wolfking.converter.dropdown.ParameterDropDown;
import com.wolfking.converter.transform.AbstractExtendTransform;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

import java.util.Set;

@Slf4j
@Component
public class ClassnameConfig implements CommandLineRunner {


    @Value("${converter.package:}")
    private String converterPackage;

    @Value("${dropdown.package:}")
    private String dropdownPackage;

    private final Set<String> transformClassSet = Sets.newHashSet();


    private final Set<String> dropDownClassSet = Sets.newHashSet();

    @Override
    @SuppressWarnings("all")
    public void run(String... args) throws Exception {
        String name = ClassnameConfig.class.getPackage().getName();
        name = name.substring(0, name.lastIndexOf("."));
        //加载包 com.weicai.operate.converter.transform.extend 下面的转换器，不需要其他的额外的add
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AssignableTypeFilter(AbstractExtendTransform.class));
        for (BeanDefinition beanDefinition : scanner.findCandidateComponents(name + ".transform.extend")) {
            if (!beanDefinition.isAbstract())
                transformClassSet.add(ClassUtils.forName(beanDefinition.getBeanClassName(), Thread.currentThread().getContextClassLoader()).getName());
        }

        if (StringUtils.isNotBlank(converterPackage)) {
            for (String packageName : converterPackage.split(",")) {
                for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
                    if (!beanDefinition.isAbstract())
                        transformClassSet.add(ClassUtils.forName(beanDefinition.getBeanClassName(), Thread.currentThread().getContextClassLoader()).getName());
                }
            }
        }

        for (String classname : transformClassSet) {
            log.info("extend transform class is {}", classname);
        }


        scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AssignableTypeFilter(ParameterDropDown.class));
        for (BeanDefinition beanDefinition : scanner.findCandidateComponents(name + ".dropdown")) {
            if (!beanDefinition.isAbstract())
                dropDownClassSet.add(ClassUtils.forName(beanDefinition.getBeanClassName(), Thread.currentThread().getContextClassLoader()).getName());
        }

        if (StringUtils.isNotBlank(dropdownPackage)) {
            for (String packageName : dropdownPackage.split(",")) {
                for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
                    if (!beanDefinition.isAbstract())
                        dropDownClassSet.add(ClassUtils.forName(beanDefinition.getBeanClassName(), Thread.currentThread().getContextClassLoader()).getName());
                }
            }
        }

        for (String classname : dropDownClassSet) {
            log.info("drop down class is {}", classname);
        }
    }

    public Set<String> getTransformClassSet() {
        return transformClassSet;
    }

    public Set<String> getDropDownClassSet() {
        return dropDownClassSet;
    }
}
